home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / mac / files / amiga / csrc720j.lzh / mbfwdx.c < prev    next >
C/C++ Source or Header  |  1993-02-01  |  31KB  |  1,399 lines

  1. /*  Keep a copy of the original mbfwd in case I don't get anywhere
  2.  *  MBFWD.C - 6/28/91 - Autoforwarding.
  3.  *
  4.  *  The target port mode is set to idle if not connected,
  5.  *  set to remote if connected. It is set to disconnect or timeout
  6.  *  by getdat(), but this is checked and fixed up in getln().
  7.  *
  8.  *  All port input is through getln().
  9.  *  All file input is through nxtin().
  10.  */
  11.  
  12. #include "mb.h"
  13.  
  14. #ifdef MCH_AMIGA
  15. unsigned short all_number = 0;
  16. extern char fbb_direction;
  17. extern short debug;
  18. extern char tmpstr[];
  19. extern char passchr,hfstream,vhfstream;
  20. FILE *tmp_file;  /*FIX 9*/
  21. extern short thebox,kambbs;
  22. extern char hostport;
  23. #define deepmax    5     /* Max nesting depth of indirection in fwd.mb */
  24. #else
  25. #define deepmax    8     /* Max nesting depth of indirection in fwd.mb */
  26. #endif
  27.  
  28. #define fw_one     0x0001  /* Forward to only one MailBox, given in fcall*/
  29. #define fw_anytime 0x0002  /* Ignore the times in the "G" item           */
  30. #define fw_abort   0x0004  /* Abort forwarding as soon as possible       */
  31. #define fw_tried   0x0008  /* Attempted to forward to this MailBox       */
  32. #define fw_tiout   0x0010  /* Forward timeout flag                       */
  33. #define fw_forced  0x0020  /* Forced forward flag                        */
  34. #define fw_pass    0x0040  /* Bypass forward sub file                    */
  35. #define fw_idle    0x0080  /* Manual forward to idle                     */
  36. #define fw_ecall   0x0100  /* Forced forward ecall                       */
  37.  
  38. char  *script;           /* Pointer to where the connect script is     */
  39.  
  40. word  fopts;             /* Options, see defines above.                */
  41. char  fwdtyp;
  42. char  *fwdfile;          /* The file name of fwd.mb root file          */
  43. FILE  *ifl[deepmax];     /* File variables for fwd.mb                  */
  44. short deep;              /* Current depth within fwd.mb                */
  45. char  path[80];          /* "G" item saved here, for logging           */
  46. char  fcall[10];         /* Call of the MailBox to forward to          */
  47.  
  48. /*
  49.  *  YF command: change the name of the forwarding root file.
  50.  */
  51.  
  52. newfwd()
  53. {
  54.    if(*port->fld[1]) {
  55. #ifdef MCH_AMIGA
  56. /* FIX 9 */
  57. /* complain if specified fwdfile can't be found */
  58.       if((tmp_file = fopen(port->fld[1],"r")) == NULL) {
  59.          sprintf(tmp->scr,"can't find %s\n",port->fld[1]);
  60.          outstr(tmp->scr);
  61.       }
  62.       else {
  63.          fclose(tmp_file);
  64. #endif
  65.          free(fwdfile);
  66.          fwdfile = strdup(port->fld[1]);
  67. #ifdef MCH_AMIGA
  68.          titles();
  69.       }
  70. #endif
  71.    }
  72.    sprintf(tmp->scr, "is %s\n", fwdfile);
  73.    outstr(tmp->scr);
  74. }
  75.  
  76. /*
  77.  *  YF forward command: change the name of the forwarding root file.
  78.  */
  79.  
  80. newffwd()
  81. {
  82.    if(*cport->fld[1]) {
  83.       free(fwdfile);
  84.       fwdfile = strdup(cport->fld[1]);
  85.    }
  86. #ifndef MCH_AMIGA
  87.    printf("<File is %s>\n", fwdfile);
  88. #else
  89.    titles();
  90. #endif
  91. }
  92.  
  93. /*
  94.  *  Add a call to the list of BBS that have messages to be forwarded to them.
  95.  */
  96.  
  97. addbfwd(cp)
  98. char *cp;
  99. {
  100.    register short i;
  101.    register char *lp;
  102.  
  103.    for(i = 0, lp = bfwd; i < bfwdn; i++, lp += ln_call)
  104.       if(matchn(cp, lp, ln_call))
  105.          return;
  106.  
  107.    if(bfwdn < bfwdm) {
  108.       strncpy(lp, cp, ln_call);
  109.       bfwdn++;
  110.    }
  111. }
  112.  
  113. /*
  114.  *  Add a call to the list of users that have unread messges.
  115.  */
  116.  
  117. addufwd(cp)
  118. char *cp;
  119. {
  120.    register short i;
  121.    register char *lp;
  122.  
  123.    for(i = 0, lp = ufwd; i < ufwdn; i++, lp += ln_call)
  124.       if(matchn(cp, lp, ln_call))
  125.          return;
  126.  
  127.    if(ufwdn < ufwdm) {
  128.       strncpy(lp, cp, ln_call);
  129.       ufwdn++;
  130.    }
  131. }
  132.  
  133. /*
  134.  *  Check if a call has a message to be forwarded to it.
  135.  */
  136.  
  137. findfwd(cp, lp, n)
  138. char *cp, *lp;
  139. short n;
  140. {
  141.    register short i;
  142.  
  143.    for(i = 0; i < n; i++, lp += ln_call)
  144.       if(wcm(cp, lp))
  145.          return true;
  146.    return false;
  147. }
  148.  
  149. /*
  150.  *  Add the info from one message header to the lists of calls
  151.  *  of stations that have messages to be forwarded to them.
  152.  *
  153.  *  ufwd - Calls to put in beacon line.
  154.  *  bfwd - Calls that have message TO or AT.
  155.  */
  156.  
  157. addfwd()
  158. {
  159.    register short i;
  160.    char *p, hcall[6];
  161.  
  162.    if(!(port->mmhs->stat & (m_busy | m_kill | m_read | m_fwd | m_hold))) {
  163.       if(*port->mmhs->bbs is ' ') {
  164.          addufwd(port->mmhs->to);
  165.          addbfwd(port->mmhs->to);
  166.       }
  167.       else {
  168.          if(port->mmhs->ext is 1) {
  169.              for(i = 0; i < port->mmhs->count; i++) if (port->mmhs->flag[i])
  170.                 addbfwd(port->mmhs->call[i]);
  171.          }
  172.          else {
  173.             if(matchn(port->mmhs->bbs, cport->user->call, ln_call))
  174.                 addufwd(port->mmhs->to);
  175.             else
  176.                 addbfwd(port->mmhs->bbs);
  177.             if(port->mmhs->ext is 2) {
  178.                p = port->mmhs->call[0];
  179.                while((p = strchr(p, '.')) isnt NULL) {
  180.                   p++;
  181.                   fill(hcall, ' ', ln_call);
  182.                   pcall(hcall, p);
  183.                   addbfwd(hcall);
  184.                }
  185.             }
  186.          }
  187.       }
  188.    }
  189. }
  190.  
  191. /*
  192.  *  Build the two lists of calls of stations that have
  193.  *  messages to be forwarded to them.
  194.  */
  195.  
  196. bldfwd()
  197. {
  198.    register word  h;
  199.  
  200.    ufwdn = 0;
  201.    bfwdn = 0;
  202.    read_rec(mfl, 0, (char *)mfhs);
  203. #ifdef MCH_AMIGA
  204.    check_mail();
  205.    unlock_mail();
  206. #endif
  207.    for(h = mfhs->last; h; h--) {
  208.       read_rec(mfl, h, (char *)port->mmhs);
  209.       if(!(port->mmhs->stat & (m_busy|m_kill|m_read|m_fwd|m_hold)))
  210.          addfwd();
  211. #ifdef MCH_AMIGA
  212. /* Find highest numbered message to ALL which isn't busy, killed or held */
  213.       if(!(port->mmhs->stat & (m_busy | m_kill | m_hold)))
  214.           if(matchn("ALL        ",port->mmhs->to,ln_call))
  215.              if(port->mmhs->number > all_number) {
  216.                 all_number = port->mmhs->number;
  217.              }
  218. #endif
  219.    }
  220. }
  221.  
  222. /*
  223.  *  Return true if the current time is within
  224.  *  the time window for forwarding to this MailBox.
  225.  */
  226.  
  227. chktime()
  228. {
  229.    register short c, en, st;
  230.  
  231.    if(fopts & fw_anytime) return true;
  232.    curtim();
  233.    st = 10 * (int)(cport->line[2] - '0') + (int)(cport->line[3] - '0');
  234.    en = 10 * (int)(cport->line[4] - '0') + (int)(cport->line[5] - '0');
  235.    c  = 10 * (int)(l_time[0] - '0') + (int)(l_time[1] - '0');
  236.    if(st <= en)
  237.       return ((c >= st) and (c <= en));
  238.    return ((c >= st) or (c <= en));
  239. }
  240.  
  241. /*
  242.  *  Check if it is ok to forward using this list.
  243.  *  Return a pointer to the port to use for forwarding, or NULL.
  244.  */
  245.  
  246. PORTS *chkfwd()
  247. {
  248.    register PORTS *p;
  249.  
  250.    if(fopts & fw_one)
  251.       if(!match (fcall, cport->fld[1]))    { passlst(); return NULL; }
  252.    if(!chktime())                          { passlst(); return NULL; }
  253.    if((p = findport(cport->opt2)) is NULL) { passlst(); return NULL; }
  254.    if(!(p->flags & p_dofwd))               { passlst(); return NULL; }
  255.    if(fopts & fw_abort)                    { passlst(); return NULL; }
  256.    p->mode = idle;
  257.    return p;
  258. }
  259.  
  260. /*
  261.  *  Check if a disconnect happened.
  262.  */
  263.  
  264. chkdis()
  265. {
  266.    if(instat())
  267.       if(getdat())
  268.          if(isdis(port->line)) {
  269.             cmdtnc();
  270.             port->mode = idle;
  271.             return true;
  272.          }
  273.    if(port->flags & p_trans)
  274.       if(!isdcd()) {
  275.          cmdtnc();
  276.          port->mode = idle;
  277.          return true;
  278.       }
  279.    return false;
  280. }
  281.  
  282. /*
  283.  *  Read the next input line from FWD.MB,
  284.  *  or from a file referenced from FWD.MB.
  285.  *  Return NULL if no more lines to read.
  286.  */
  287.  
  288. char *nxtin(p)
  289. char *p;
  290. {
  291.    register char *st, i;
  292.  
  293.    while(deep >= 0) {
  294.       i = 1;
  295.       if((st = fgets(p, 80, ifl[deep])) is NULL) {
  296.          fclose(ifl[deep]);
  297.          deep--;
  298.       }
  299.       else {
  300.          if(*p isnt '@') return st;
  301.          if(fopts & fw_pass) return st;
  302.          if(*(p+1) is ' ') {
  303.             if(!chktime()) return st;
  304.             i = 6;
  305.          }
  306.          if(deep < (deepmax - 1)) {
  307.             strupr(p);
  308.             remnl(p);
  309.             deep++;
  310.             if((ifl[deep] = fopen(p + i, "r")) is NULL) deep--;
  311.          }
  312.       }
  313.    }
  314.    return NULL;
  315. }
  316.  
  317. /*
  318.  *  Do some DOS commands.
  319.  */
  320.  
  321.  
  322. dofdos()
  323. {
  324.    register PORTS *p;
  325.  
  326.    if((p = findport(cport->opt2)) is NULL) {
  327.       passlst();
  328.       return;
  329.    }
  330. #ifdef MCH_AMIGA
  331. /* Don't do this if the port doesn't forward! */
  332.    if((p->flags & p_dofwd) == 0) {
  333.       passlst();
  334.       return;
  335.    }
  336. #endif
  337.    if(strlen(cport->fld[0]) > 3)
  338.       if(!chktime()) {
  339.          passlst();
  340.          return;
  341.       }
  342.    if(fopts & fw_forced)
  343.       if(!((fopts & fw_one) and (match(fcall, cport->fld[1])))) {
  344.          passlst();
  345.          return;
  346.       }
  347.  
  348. /*
  349.  *  Just in case, flush whatever might be currently open.
  350.  */
  351.  
  352.    clnuser();
  353.    clnmsg();
  354.    clnlog();
  355.  
  356.    while(nxtin(cport->line) isnt NULL) {
  357.       if(iseof(cport->line)) return;
  358.       remnl(cport->line);
  359. #ifndef MCH_AMIGA
  360.       printf("\nRunning: %s\n", cport->line);
  361.       if(system(cport->line)) perror("Error");
  362. #else
  363.       sprintf(tmpstr,"\nRunning: %s\n", cport->line);
  364.       ttputs(tmpstr);
  365.       /* MANX doesn't like above syntax ..
  366.          gotta explicitly generate address
  367.       */
  368.       if(do_system(&cport->line[0])) perror("Error");
  369. #endif
  370.    }
  371. }
  372.  
  373. /*
  374.  *  The entry to fowarding.
  375.  */
  376.  
  377. fwd()
  378. {
  379.    register PORTS *p;
  380.  
  381. /*
  382.  *  If no fwd.mb file, then do nothing.
  383.  */
  384. printf("FWD dir=%d f='%6.6s' t='%6.6s'\n",fbb_direction,fcall,tcall);
  385.    deep = 0;
  386.    if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) return;
  387.  
  388.    bldfwd();
  389.  
  390.    script = tmp->scr;
  391.    *script = '\0';
  392.  
  393.    while(nxtin(cport->line) isnt NULL) {
  394. #ifdef MCH_AMIGA
  395.       kambbs = thebox = 0;
  396.  
  397.       if(!fbb_direction)s_mart = 0;
  398. #else
  399.       s_mart = 0;
  400. #endif
  401.       ioport(cport);
  402.       strupr(cport->line);
  403.       parse();
  404.       fwdtyp = cport->opt1;
  405.       switch(fwdtyp) {
  406.       case 'E':
  407.          passlst();
  408.          script = tmp->scr;
  409.          *script = '\0';
  410.          break;
  411.       case 'D':
  412.       case 'F':
  413.       case 'G':
  414.       case 'H':
  415.          if((p = chkfwd()) isnt NULL) {
  416.             fopts clrbit fw_tried;
  417. /*
  418.  *  Save tail of list header for logging.
  419.  */
  420.             strcpy(path, cport->line + 6);
  421.             remnl(path);
  422. #ifndef MCH_AMIGA
  423.             strcpy(fcall, cport->fld[1]);
  424. #else
  425.             pcall(fcall,cport->fld[1]);
  426. #endif
  427.             script = tmp->scr;
  428.             if(!*script) {
  429.                *script = 'C';
  430.                strcpy(script + 1, cport->line + 6);
  431.                *(script + strlen(script) + 1) = '\0';
  432.             }
  433. #ifndef MCH_AMIGA
  434.             dofwd(p);
  435.             dorev(p);
  436. #else
  437.             user_title(fcall);
  438.             /* chkfwd() forces do_idle ... have to set it to remote for
  439.                a BBS which has called us
  440.             */
  441.             if(fbb_direction)p->mode = remote;
  442.             dofwd(p);
  443.             if((s_mart & fbbok) == 0) {
  444.                dorev(p);
  445.             }
  446.             user_title("");
  447. #endif
  448.             distnc();
  449.             p->mode = idle;
  450.             ioport(cport);
  451.          }
  452.          script = tmp->scr;
  453.          *script = '\0';
  454.          break;
  455.  
  456.       case 'P':
  457.          dopar();
  458.          break;
  459.  
  460.       case '!':
  461.          dofdos();
  462.          break;
  463.  
  464.       case 'Y':
  465. #ifdef MCH_AMIGA
  466. /* Only do the 'YF' at the end of the file if this is NOT the console
  467.    port forwarding time
  468. */
  469.          if((cport->flags & p_dofwd) == 0)
  470. #endif
  471.          if((cport->opt2 is 'F') and (chktime() ))
  472.             newffwd();
  473.          break;
  474.  
  475.       case 'C':
  476.       case 'R':
  477.       case 'S':
  478.          strcpy(script, cport->line);
  479.          script += (strlen(cport->line) + 1);
  480.          *script = '\0';
  481.          break;
  482.  
  483.       default:
  484.          break;
  485.       }
  486.    }
  487.  
  488. /*
  489.  *  Put us back on the port we were on when we got here.
  490.  */
  491.  
  492.    ioport(cport);
  493. #ifdef MCH_AMIGA
  494.    kambbs = thebox = 0;
  495. #endif
  496.    s_mart = 0;
  497. }
  498.  
  499. /*
  500.  *  A and AI commands.
  501.  */
  502.  
  503. #ifndef MCH_AMIGA
  504. all_fwd()
  505. {
  506.    word pflg;
  507.    port->opt1 = 'X';
  508.    putcomd( port->opt1, port->opt2 );
  509.  
  510.    pflg = getp_flag();
  511.    putc_flag (pflg);
  512.    port->mode = logout;
  513. }
  514. #endif
  515.  
  516. /*
  517.  *  X and XI commands.
  518.  */
  519.  
  520. sfwd()
  521. {
  522.    register PORTS *p;
  523.  
  524. /*
  525.  *  If remote sysop did the command, just remember it for later.
  526.  */
  527.  
  528.    if(port->mode & sysop) {
  529.       savecmd();
  530.       return;
  531.    }
  532.  
  533. /*
  534.  *  Set up parameters for fwd()
  535.  */
  536.  
  537.    fopts = fw_forced;
  538.    for(p = porthd; p isnt NULL; p = p->next) {
  539.       p->ec = p->ecuser;
  540.       p->flags setbit p_dofwd;
  541.    }
  542.  
  543.    if(cport->flds > 1) {
  544.       fopts setbit fw_one;
  545.       strncpy (fcall, cport->fld[1], ln_callp);
  546.    }
  547.    if(cport->flds is 3) {
  548.       fopts setbit fw_ecall;
  549.       pcall(tcall, cport->fld[2]);
  550.    }
  551.  
  552.    if((cport->opt2 is 'I')or(cport->opt2 is 'B'))
  553.       fopts setbit fw_anytime;
  554.    if(cport->opt2 is 'B')
  555.       fopts setbit fw_idle;
  556. #ifdef MCH_AMIGA
  557. /* Tell fbb that we called */
  558.    fbb_direction = 0;
  559. #endif
  560.    fwd();
  561.  
  562. /*
  563.  *  Reset the port flags.
  564.  */
  565.  
  566.    for(p = porthd; p isnt NULL; p = p->next)  {
  567.       p->ec = p->ecmon;
  568.       p->flags clrbit p_dofwd;
  569.    }
  570.    if(fopts & fw_idle) bye();
  571.  
  572. }
  573.  
  574. /*
  575.  *  Automatic forwarding.
  576.  *  Called once each minute when the MailBox is idle.
  577.  */
  578.  
  579. afwd(curmin)
  580. int curmin;
  581. {
  582.    register PORTS *p;
  583.    register short anyfwd;
  584.  
  585. #ifdef MCH_AMIGA
  586. /* FIX 14 The setunt routine can be called with the TNC as the port
  587.           and in that case it will send all output from an automatic
  588.           untangle to the TNC as well as the console.
  589. */
  590.    register PORTS *saveport;
  591.  
  592.    saveport = port;
  593.  
  594. /* Tell fbb that we called */
  595.    fbb_direction = 0;
  596. #endif
  597.  
  598. /*
  599.  *  Mark the ports that should forward at this minute.
  600.  */
  601.  
  602.    fopts = 0;
  603.    anyfwd = false;
  604.    for(p = porthd; p isnt NULL; p = p->next)
  605.       if(p->fwdmin is curmin) {
  606.  
  607. #ifdef MCH_AMIGA
  608. /* Console only forwards from the process running port A */
  609.          if((p->id == 'Z') && (hostport != 'A'))continue;
  610. #endif
  611.  
  612.          p->flags setbit p_dofwd;
  613.          p->ec = p->ecuser;
  614.          anyfwd = true;
  615.       }
  616.  
  617. /*
  618.  *  If any ports forward at this minute, do the forwarding.
  619.  */
  620.  
  621.    if(anyfwd) {
  622.       setbusy();
  623.       alloff();   /* Turn off connects and monitoring */
  624.       if(s_flag & s_dv) begin_lock();
  625.       readmsg();
  626.       readusr();
  627.  
  628. /*
  629.  *  Write out mon and calls heard files
  630.  */
  631.       clsmon();
  632.  
  633. /*
  634.  *  Once a day, do wp and stale
  635.  */
  636.       if(!matchn(ufhs->wpdate, l_date, ln_date)) {
  637.          port->opt1 = '\0';
  638.          port->flds = 1;
  639.          if(s_flag & s_dv) end_lock();
  640. #ifdef MCH_AMIGA
  641.          lock_user();
  642. #endif
  643.          dwuser();
  644.          if(s_flag & s_dv) begin_lock();
  645.          stale();
  646.          strncpy(ufhs->wpdate, l_date, ln_date);
  647.          write_rec(ufl, 0, (char *)ufhs);
  648. #ifdef MCH_AMIGA
  649.          unlock_user();
  650. #endif
  651.       }
  652.       if(s_flag & s_dv) end_lock();
  653.  
  654. /*
  655.  * Check and see if the mailfile should be compressed
  656.  */
  657.       if(s_param & s_unt)
  658.       if(!matchn(mfhs->date, l_date, ln_date))
  659.       if(unt_hr <= (10 *(l_time[0] - '0') + (l_time[1] - '0')))
  660.       {
  661. #ifdef MCH_AMIGA
  662.          ioport(cport);
  663. #endif
  664.          port->opt2 = 'A';
  665.          setunt();
  666. #ifdef MCH_AMIGA
  667.          ioport(saveport);
  668. #endif
  669.       }
  670.  
  671.       fwd();
  672.       clnlog();
  673.       setfwd();
  674.       clsmsg();
  675.       clsusr();
  676.       allon();    /* Turn on monitoring and connects */
  677.       clrbusy();
  678.    }
  679.  
  680. /*
  681.  *  Reset the port flags.
  682.  */
  683.  
  684.    for(p = porthd; p isnt NULL; p = p->next) {
  685.       p->ec = p->ecmon;
  686.       p->flags clrbit p_dofwd;
  687.    }
  688. }
  689.  
  690. /*
  691.  *  Reverse forwarding.
  692.  *  Accept messages from the remote MailBox after forwarding to it.
  693.  */
  694.  
  695. dorev(p)
  696. PORTS *p;
  697. {
  698.    char rcall[6];
  699.    ioport(p);
  700. printf("DOREV\n");
  701.    if(fwdtyp is 'G') return;
  702.    if(fwdtyp is 'D') return;
  703.  
  704.    if(p->mode & idle) {
  705.       if(fwdtyp is 'F')
  706.          return;
  707.       if(fwdtyp is 'H')
  708.          if(fopts & fw_tried)
  709.             return;
  710.       cmb();
  711.       if(p->mode & idle) return;
  712.    }
  713.  
  714.    pcall(rcall, path + 2);
  715.    rduser(rcall, p->user);
  716.    log('M', 'F', 'R', path);  /* Log start of reverse forward */
  717. #ifdef MCH_AMIGA
  718.    user_title(p->user->call);
  719.    /* dorev can be called if dofwd does not find anything to send!
  720.       Call fbbfwd before setting transparent mode ... it's done in
  721.       fbbfwd.
  722.    */
  723.    if(s_mart & fbbok) {
  724.       fbb_direction = 0;
  725.       fbbfwd(0);
  726.       return;
  727.    }
  728.  
  729. #endif
  730.  
  731.    if(p->tmode) {
  732.       cmdtnc();
  733.       trantnc();
  734.    }
  735.  
  736.    while(true) {
  737.       outstr("F>\n");
  738.       getln();
  739.       if(p->mode & idle) return;
  740.       parse();
  741.  
  742.       if(p->opt1 isnt 'S') return;
  743.       sndmsg();
  744.       if(p->mode & gone) return;
  745.       addfwd();
  746.    }
  747. }
  748.  
  749. /*
  750.  *  F> command: do reverse forward to logged user.
  751.  */
  752.  
  753. fwdcmd()
  754. {
  755.    register PORTS *p;
  756.    register short ok;
  757.  
  758. /*
  759.  *  If no fwd.mb file, then do nothing.
  760.  */
  761.  
  762. printf("FWDCMD dir=%d f='%6.6s' t='%6.6s'\n",fbb_direction,fcall,tcall);
  763.    p = port;
  764.    deep = 0;
  765.    if((ifl[deep] = fopen(fwdfile, "r")) is NULL) {
  766.       p->mode = forced;
  767.       return;
  768.    }
  769.  
  770.    ioport(cport);
  771.  
  772. /*
  773.  *  Find the users E, F, G, or H list in the fwd.mb file.
  774.  */
  775.  
  776.    ok = false;
  777.    while(!ok and (nxtin(cport->line) isnt NULL)) {
  778.       strupr(cport->line);
  779.       parse();
  780.       fwdtyp = cport->opt1;
  781.  
  782.       switch(fwdtyp) {
  783.       case 'D':
  784.       case 'E':
  785.       case 'F':
  786.       case 'G':
  787.       case 'H':
  788.          pcall(fcall, cport->fld[1]);
  789.          ok = matchn(fcall, p->user->call, ln_call);
  790.  
  791.          if (!ok) passlst();
  792.          break;
  793.  
  794.       case '!':
  795.       case 'P':
  796.          passlst();
  797.          break;
  798.  
  799.       default  : ;   /* 'C', 'R', 'S', 'Y' */
  800.       }
  801.    }
  802.  
  803.    ioport(p);
  804.  
  805.    if(ok) {
  806.       log ('M', 'F', 'S', nullstr);      /* Log start of forwarding */
  807.       bldfwd();
  808.       remnl(cport->line);
  809.       strcpy( path, cport->line+6 );
  810.       dofwd(p);
  811.       log ('M', 'F', 'E', nullstr);      /* Log end of forwarding */
  812.    }
  813.  
  814.    while(deep >= 0) {
  815.       fclose(ifl[deep]);
  816.       deep--;
  817.    }
  818.    if(p->mode is idle) return;
  819. #ifndef MCH_AMIGA
  820.    outstr("*** Done.\n");
  821. #else
  822.    /* It seems that some BBS do not like "Done" so we'll just drop out */
  823.    distnc();
  824. #endif
  825. }
  826.  
  827. /*
  828.  *  Pass a sublist in the forwarding file.
  829.  */
  830.  
  831. passlst()
  832. {
  833.    fopts setbit fw_pass;
  834.    while(true) {
  835.       if(nxtin(cport->line) is NULL) {
  836.          fopts clrbit fw_pass;
  837.          return;
  838.       }
  839.       if(iseof(cport->line)) {
  840.          fopts clrbit fw_pass;
  841.          return;
  842.       }
  843.    }
  844. }
  845.  
  846. /*
  847.  *  Set tnc parameters.
  848.  */
  849.  
  850. dopar()
  851. {
  852.    register PORTS *p;
  853.  
  854.    if((p = findport(cport->opt2)) is NULL) {
  855.       passlst();
  856.       return;
  857.    }
  858. #ifdef MCH_AMIGA
  859. /* Don't do this if the port doesn't forward at this time */
  860.    if((p->flags & p_dofwd) == 0) {
  861.       passlst();
  862.       return;
  863.    }
  864. #endif
  865.  
  866.    if(strlen(cport->fld[0]) > 3)
  867.       if(!chktime()) {
  868.          passlst();
  869.          return;
  870.       }
  871.  
  872.    ioport(p);
  873.    while(nxtin(cport->line) isnt NULL) {
  874.       if(iseof(cport->line)) {
  875.          ioport(cport);
  876.          return;
  877.       }
  878.       onetnc(cport->line);
  879.    }
  880.    ioport(cport);
  881. }
  882.  
  883. /*
  884.  *  Get a line from the current port.
  885.  *  Handle disconnect, timeout, and ^F.
  886.  */
  887.  
  888. getln()
  889. {
  890.    while(!getdat());
  891.    if(port->mode & forced) fopts setbit fw_abort;
  892.    if(port->mode & gone) {
  893.       distnc();
  894.       port->mode = idle;
  895.    }
  896. }
  897.  
  898. /*
  899.  *  Eat the remote MailBox prompt.
  900.  */
  901.  
  902. eat()
  903. {
  904.    register char c;
  905.    if(fwdtyp is 'D') c = ':';
  906.    else              c = '>';
  907.    while(true) {
  908.       getln();
  909.       if(!(port->mode & remote)) return;
  910.       if(port->line[0] is '[') isbid();
  911.       if((port->mode & remote) and
  912.                              (port->line[strlen(port->line) - 2] is c)) {
  913.          return;
  914.     }
  915.   } 
  916. }
  917.  
  918. /*
  919.  *  Connect to a remote Mailox.
  920.  *  Port mode idle at entry.
  921.  *  On return, port mode is remote if the connect worked, else idle.
  922.  */
  923.  
  924. cmb()
  925. {
  926.    port->flags setbit p_dotmr;
  927.    port->mode = remote;
  928.  
  929. /*
  930.  * Execute the connect script.
  931.  */
  932.    while(*script) {
  933.       switch(*script++) {
  934.       case 'C':
  935.          contnc(script);
  936.          if(port->mode & idle) return;
  937.          if(port->dev is p_tnc)
  938.             do {
  939.                getln();
  940.                if(port->mode & idle) return;
  941.             }
  942.          while(!iscon(port->line));
  943.          break;
  944.  
  945.       case 'S':
  946.          outstr(script);
  947.          break;
  948.  
  949.       case 'R':
  950.          getln();
  951.          if(port->mode & idle) return;
  952.          strupr(port->line);
  953.          if(*script isnt '!')
  954. #ifndef MCH_AMIGA
  955.             if(!search(port->line, script, strlen(script)-1))
  956. #else
  957. /* The new Manx 5.0 compiler uses a LONG for strlen AND for
  958.    sizeof so must change things a bit
  959. */
  960.             if(!search(port->line, script, (short)strlen(script)-1))
  961. #endif
  962.             {
  963.                distnc();
  964.                port->mode = idle;
  965.                return;
  966.             }
  967.          break;
  968.  
  969.       default: ;
  970.       }
  971.       while(*script++);  /* Move to next script line */
  972.    }
  973.  
  974. /*
  975.  *  In theory, now connected to MailBox. Eat login messge.
  976.  */
  977.  
  978.    eat();
  979.    if(!(port->mode & remote)) return;
  980.    if(s_mart) {
  981.       outstr(vers);
  982. #ifdef MCH_AMIGA
  983. /* If we called them and they are an fbb system, don't call eat().
  984. */
  985.       if(s_mart & fbbok) {
  986.          return;
  987.       }
  988. #endif
  989.       eat();
  990.    }
  991. }
  992.  
  993. /*
  994.  *  Forward whatever messages go to this MailBox.
  995.  */
  996.  
  997. dofwd(p)
  998. PORTS *p;
  999. {
  1000.    register char *st;
  1001. printf("DOFWD dir=%d f='%6.6s' t='%6.6s'\n",fbb_direction,fcall,tcall);
  1002.    filesize = 0;
  1003.    st = nxtin(cport->line);
  1004.    while(!iseof(cport->line) and (st isnt NULL)) {
  1005.       if(!(fopts & fw_ecall)) {
  1006.          ioport(cport);
  1007.          parse();
  1008.          if(cport->opt1 is '<')
  1009.             if(chktime())
  1010.                if(!(fopts & fw_anytime))
  1011.                   filesize = atoi(cport->fld[1]);
  1012.          pcall (tcall, cport->fld[0]);
  1013.       }
  1014.       ioport(p);
  1015. #ifndef MCH_AMIGA
  1016.       if(findfwd(tcall, bfwd, bfwdn)) {
  1017. #else
  1018.       if(((s_mart & fbbok) && fbb_direction)
  1019.                                          || findfwd(tcall, bfwd, bfwdn)) {
  1020. #endif
  1021.          fmsg();
  1022.          if(fopts & fw_tried)
  1023.             if(p->mode & idle) {
  1024.                p->mmhs->stat clrbit m_busy;
  1025.                wt_mmhs();
  1026.                passlst();
  1027.                return ;
  1028.             }
  1029.       }
  1030.       if (fopts & fw_ecall) fopts clrbit fw_ecall;
  1031.       else st = nxtin(cport->line);
  1032.    }
  1033. }
  1034.  
  1035. /*
  1036.  *  Send the message text.
  1037.  */
  1038.  
  1039. xmtmsg()
  1040. {
  1041.    register FILE *fl;
  1042. #ifdef MCH_AMIGA
  1043.    register char *cp,*pp;
  1044. #endif
  1045.  
  1046.    sprintf(port->line, "%s%u", msgdir, port->mmhs->number);
  1047.    if((fl = fopen(port->line, "r")) is NULL)
  1048.       nofile(port->line);
  1049.    else {
  1050.       fseek(fl, (long)RECSIZE, 0);
  1051.       while(fgets(tmp->scr, scrmax, fl) isnt NULL) {
  1052.          if(chkdis()) {
  1053.             fclose(fl);
  1054.             return false;
  1055.          }
  1056. #ifdef MCH_AMIGA
  1057.          for(cp = tmp->scr,pp = &tmpstr[0];*cp && (pp < &tmpstr[200]);cp++) {
  1058.             if(*cp == passchr)continue;
  1059.             /* insert the pass character for stream characters */
  1060.             if(passchr) {
  1061.                if((*cp == vhfstream) || (*cp == hfstream)) {
  1062.                   *pp++ = passchr;
  1063.                }
  1064.                *pp++ = *cp;
  1065.                continue;
  1066.             }
  1067.             if((*cp >= ' ') && (*cp <= 0176)) {
  1068.                *pp++ = *cp;
  1069.                continue;
  1070.             }
  1071.             /*
  1072.                Allow BEL BS HT LF VT FF and CR through.
  1073.                All others are omitted
  1074.             */
  1075.             if((*cp >= 7) && (*cp <= '\r')) {
  1076.                *pp++ = *cp;
  1077.                continue;
  1078.             }
  1079.          }
  1080.          *pp = 0;
  1081.          outstr(tmpstr);
  1082. #else
  1083.          outstr(tmp->scr);
  1084. #endif
  1085.       }
  1086.       fclose (fl);
  1087.    }
  1088.    if(fwdtyp is 'D') {
  1089.       outstr(".\n");
  1090.       outstr("y\n");
  1091.    }
  1092.    else {
  1093.       outchar(cpmeof);
  1094.       outchar('\n');
  1095.    }
  1096.    return true;
  1097. }
  1098.  
  1099. /*
  1100.  *  Forward all messages TO or AT tcall
  1101.  *  to the MailBox we are connected to.
  1102.  */
  1103.  
  1104. fmsg()
  1105. {
  1106.    char *a, *b, *c;
  1107.    char hcall[6];
  1108.    register PORTS *p;
  1109.    register word h;
  1110.    register short i, ok, extnr, hasit;
  1111. printf("FMSG - '%6.6s'\n",tcall);
  1112.    hasit = true;   /* just initialize it to something */
  1113.  
  1114.    p = port;
  1115. #ifdef MCH_AMIGA
  1116.    check_mail();
  1117.    unlock_mail();
  1118. #endif
  1119.    for(h = mfhs->last; h; h--) {
  1120.       if(s_flag & s_dv) begin_lock();
  1121. #ifndef MCH_AMIGA
  1122. /* Put all this in check_ok() so that fbb can sort out whether to send a
  1123.    message or not
  1124. */
  1125.       read_rec(mfl, h, (char *)p->mmhs);
  1126.  
  1127.       ok = (!(p->mmhs->stat & (m_kill|m_read|m_fwd|m_hold|m_busy)));
  1128.  
  1129.       if(ok)
  1130.          if(filesize)
  1131.             ok = filesize > p->mmhs->size;
  1132. /*
  1133.  *  Decide whether to forward this one.
  1134.  */
  1135.       if(ok) {
  1136. #ifndef MCH_AMIGA
  1137.          if (p->mmhs->ext is 1)
  1138. #else
  1139. /* Fix bug. A bulletin should only be forwarded to the connected station
  1140.    IF and ONLY IF the connected station has not yet received it.
  1141.    This code sends it back to the calling station if one of the stations
  1142.    in the distribution list for the bulletin is also in the collection
  1143.    list for the connected station
  1144.  
  1145.    NOT SURE THIS IS RIGHT
  1146. */
  1147.          if((p->mmhs->ext == 1) /* && matchn(fcall,tcall,ln_call)*/)
  1148. #endif
  1149.          {
  1150.             ok = false;
  1151.             for(i = 0; !ok and (i < p->mmhs->count); i++)
  1152.                if(p->mmhs->flag[i])
  1153.                   if(wcm(tcall, p->mmhs->call[i])) {
  1154.                      ok = true;
  1155.                      extnr = i;
  1156.                   }
  1157.          }
  1158.          else if(*p->mmhs->bbs isnt ' ') {
  1159.             ok = wcm(tcall, p->mmhs->bbs);
  1160.             if(!ok) if(p->mmhs->ext is 2) {
  1161.                c = p->mmhs->call[0];
  1162.                while(!ok and ((c=strchr(c, '.')) isnt NULL)) {
  1163.                   c++;
  1164.                   fill(hcall, ' ', ln_call);
  1165.                   pcall(hcall, c);
  1166.                   ok = wcm(tcall, hcall);
  1167.                }
  1168.             }
  1169.          }
  1170.          else
  1171.             ok = wcm(tcall, p->mmhs->to);
  1172.       }
  1173. #else
  1174. /* kludge a way to get extnr passed through. check_ok returns extnr if it
  1175.    is set (which implies ok and -1 if ok but extnr not set. Zero otherwise.
  1176.    extnr is only used  if ->ext == 1  which is only way it could be set
  1177. */
  1178.       ok = check_ok(h);
  1179.       if(ok > 0)extnr = ok-1;
  1180.  
  1181. #endif
  1182.  
  1183.       if(ok) {
  1184.          p->mmhs->stat setbit m_busy;
  1185.          wt_mmhs();
  1186.       }
  1187.       if(s_flag & s_dv)
  1188.          end_lock();
  1189.  
  1190. /*
  1191.  *  If we DO forward this one, forward this one.
  1192.  */
  1193.       if(ok) {
  1194.          if(fopts & fw_tiout) {
  1195.             wait (p->ftime);
  1196.             fopts clrbit fw_tiout;
  1197.          }
  1198.          fopts setbit fw_tried;
  1199.          if(p->mode & idle) cmb();
  1200.          if(p->mode & idle) return;
  1201. #ifdef MCH_AMIGA
  1202.          if(s_mart & fbbok) {
  1203.          /* This is ugly .. have to release the first message to be sent so
  1204.             that fbbfwd can find it again. There's got to be a better way!
  1205.             But the forwarding routine doesn't do anything until it has
  1206.             found the first message to forward.
  1207.          */
  1208.             p->mmhs->stat clrbit m_busy;
  1209.             wt_mmhs();
  1210.             pcall(hcall, path + 2);
  1211.             rduser(hcall, p->user);
  1212.             fbbfwd(h);
  1213.             return;
  1214.          }
  1215. #endif
  1216.          if(*p->mmhs->bbs is ' ')
  1217.             prtx("S$B $G < $P");
  1218.          else
  1219.             if((s_mart&hidok)and(p->mmhs->ext is 2))
  1220.                prtx("S$B $G @ $h < $P");
  1221.             else
  1222.                prtx("S$B $G @ $A < $P");
  1223. #ifndef MCH_AMIGA
  1224.          if(s_mart&bidok) if (*p->mmhs->bid isnt ' ') {
  1225. #else
  1226.          if(s_mart&(bidok|midok)) if (*p->mmhs->bid isnt ' ') {
  1227. #endif
  1228.             outstr(" $");
  1229.             a = p->line;
  1230.             b = p->mmhs->bid;
  1231.             unbl(a, b, ln_bid);
  1232.             outstr(p->line);
  1233.          }
  1234. #ifdef MCH_AMIGA
  1235. /* If we are talking to THEBOX and this message has a lifetime, then
  1236.    send the lifetime
  1237. */
  1238.          if(thebox && p->mmhs->lifetime) {
  1239.             sprintf(tmpstr," #%u",p->mmhs->lifetime);
  1240.             outstr(tmpstr);
  1241.          }
  1242. #endif
  1243.          outchar('\n');
  1244.          getln();
  1245.          if(p->mode & idle) return;
  1246.          if(s_mart) {
  1247.             if(*p->line < ' ') {
  1248.                getln();
  1249.                if(p->mode & idle) return;
  1250.             }
  1251.             switch(*p->line) {
  1252.             case 'O':
  1253.                hasit = false;
  1254.                outstr(p->mmhs->title);
  1255.                outchar('\n');
  1256.                break;
  1257.             case 'N':
  1258.                hasit = true;
  1259.                break;
  1260.             default:
  1261.                p->mmhs->stat clrbit m_busy;
  1262.                wt_mmhs();
  1263.                return;
  1264.             }
  1265.          }
  1266.          else {
  1267.             hasit = false;        /* you'll want to send msg */
  1268.             outstr(p->mmhs->title);
  1269.             outchar('\n');
  1270.             getln();
  1271.             if(p->mode & idle) return;
  1272.          }
  1273.          if(!hasit) {
  1274.             curtim();
  1275.             prtx(mm[4]);
  1276.             if(!xmtmsg()) {
  1277.                fopts setbit fw_tiout;
  1278.                return;
  1279.             }
  1280.          }
  1281.          eat();
  1282.          if(p->mode & idle) {
  1283.             fopts setbit fw_tiout;
  1284.             return;
  1285.          }
  1286. /*
  1287.  *  The message actually forwarded.
  1288.  *  Kill it, mark it, or whatever.
  1289.  */
  1290.          sprintf(p->line, "%u %s", p->mmhs->number, path);
  1291.          log ('M', 'F', ' ', p->line);
  1292.        
  1293.          markdis(extnr);
  1294.  
  1295.          p->mmhs->stat clrbit m_busy;
  1296.          if(p->mmhs->ext isnt 1) {
  1297.             pcall(p->mmhs->fwdc, fcall);
  1298.             p->mmhs->fport = p->id;
  1299.          }
  1300.          write_rec(mfl, p->mmhs->rn, (char *)p->mmhs);
  1301.          makehdr2();
  1302.       }
  1303.    }
  1304. #ifdef MCH_AMIGA
  1305.    /* Only get here if the loop didn't find a message to send. But still
  1306.       have to call fbbfwd to receive stuff from the other end
  1307.    */
  1308.    if(s_mart & fbbok) {
  1309.       fbbfwd(0);
  1310.    }
  1311. #endif
  1312. }
  1313. markdis(nr)
  1314. int nr;
  1315. {
  1316.   int i, kill, kok;
  1317.   kill = false;
  1318.   kok = false;
  1319. /*  If cc: list exists, mark this call as forwarded. */
  1320.  
  1321.   if (port->mmhs->ext is 1)
  1322.   {
  1323.      port->mmhs->flag[nr] = false;
  1324.      for (i = 0; i < port->mmhs->count; i++)
  1325.      if (port->mmhs->flag[i]) kok = true;
  1326.   }
  1327.  
  1328.   if (!kok)
  1329.   {
  1330.      if ((port->mmhs->type is 'B') or (port->mmhs->ext is 1))
  1331.      kill = s_param & s_fkill;
  1332.      else kill = s_param & s_kill;
  1333.   }
  1334.  
  1335.   if (kill) port->mmhs->stat setbit m_kill;
  1336.   else if (!kok) port->mmhs->stat setbit m_fwd;
  1337.  
  1338. }
  1339. #ifdef MCH_AMIGA
  1340. check_ok(h)
  1341. int h;
  1342. {
  1343.    register int ok,i,extnr;
  1344.    register char *c;
  1345.    register PORTS *p;
  1346.    char hcall[6];
  1347.  
  1348.  
  1349.    extnr = -1;
  1350.    p = port;
  1351.    read_rec(mfl, h, (char *)p->mmhs);
  1352.    ok = (!(p->mmhs->stat & (m_kill|m_read|m_fwd|m_hold|m_busy)));
  1353.    if (ok) if(filesize)  ok = filesize > p->mmhs->size;
  1354. /*
  1355.  *  Decide whether to forward this one.
  1356.  */
  1357.    if(ok) {
  1358. /* Fix bug. A bulletin should only be forwarded to the connected station
  1359.    IF and ONLY IF the connected station has not yet received it.
  1360.    The old code sent it back to the calling station if one of the stations
  1361.    in the distribution list for the bulletin was also in the collection
  1362.    list for the connected station
  1363. */
  1364.       if((p->mmhs->ext == 1)/* && matchn(fcall,tcall,ln_call)*/) {
  1365.          ok = false;
  1366.          for (i = 0; !ok and (i < p->mmhs->count); i++)
  1367.             if (p->mmhs->flag[i])
  1368.                if(wcm(tcall, p->mmhs->call[i])) {
  1369.                   ok = true;
  1370.                   extnr = i;
  1371.  
  1372.                }
  1373.       }
  1374.       else if(*p->mmhs->bbs isnt ' ') {
  1375.          ok = wcm(tcall, p->mmhs->bbs);
  1376.          if(!ok)
  1377.             if(p->mmhs->ext is 2) {
  1378.                c = p->mmhs->call[0];
  1379.                while(!ok and ((c=strchr(c, '.')) isnt NULL)) {
  1380.                   c++;
  1381.                   fill(hcall, ' ', ln_call);
  1382.                   pcall(hcall, c);
  1383.                   ok = wcm(tcall, hcall);
  1384.                }
  1385.             }
  1386.       }
  1387.       else ok = wcm(tcall, p->mmhs->to);
  1388.    }
  1389.    if(extnr >= 0) {
  1390. /* Have to return one more than extnr because it can be zero */
  1391.       return(extnr+1);
  1392.    }
  1393.    if(ok) {
  1394.       return(-1);
  1395.    }
  1396.    return(0);
  1397. }
  1398. #endif
  1399.